/* Component info --------------------------------------------------------------
 * Author   : PURESUN
 * Version  : V1.0.0
 * Notes    : json parser library
 * Update   : 2023-12-24
 ------------------------------------------------------------------------------*/

/* Define to prevent recursive inclusion --------------------------------------*/
#ifndef __JSMN_PARSER_H__
#define __JSMN_PARSER_H__

/* Includes ------------------------------------------------------------------*/
#include "jsmn.h"
#include "puresun_type.h"

/* Exported macro ------------------------------------------------------------*/
#define DEFAULT_JSON_TOKEN_SIZE 32
#define MAX_JSON_TOKEN_SIZE 1024
#define MAX_JSON_SIZE 1024 * 1024

/* Exported types ------------------------------------------------------------*/

typedef enum
{
    JSON_OK,
    JSON_ERR,
    JSON_ERR_ALLOC_MEMORY_FAILED,
    JSON_ERR_ARRAY_INDEX_NOT_NUMBER,
    JSON_ERR_ARRAY_TOKEN_IS_OUT_OF_RANGE,
    JSON_ERR_ARRAY_TOKEN_IS_NOT_ARRAY,
    JSON_ERR_ARRAY_INDEX_IS_OUT_OF_RANGE,
    JSON_ERR_ARRY_ITEM_NOT_FOUND,
    JSON_ERR_FILE_NOT_EXIST,
    JSON_ERR_JSON_PATH_IS_NULL,
    JSON_ERR_JSON_STRING_NULL,
    JSON_ERR_JSON_STRING_TOO_SHORT,
    JSON_ERR_JSON_STRING_FORMAT_ERROR,
    JSON_ERR_JSON_STRING_NOT_COMPLETE,
    JSON_ERR_JSON_TOKENS_IS_TOO_LONG,
    JSON_ERR_KEY_PATH_IS_NULL,
    JSON_ERR_KEY_NOT_FOUND,
    JSON_ERR_KEY_NOT_NUMBER,
    JSON_ERR_KEY_NOT_STRING,
    JSON_ERR_KEY_NOT_PRIMITIVE, // bool, null
    JSON_ERR_KEY_NOT_ARRAY,
    JSON_ERR_KEY_PATH_INVALID_ARRAY_INDEX,
    JSON_ERR_MAX_LEN_IS_NEGATIVE,
    JSON_ERR_OBJECT_TOO_LONG,
    JSON_ERR_OUT_IS_NULL,
    JSON_ERR_TOKENID_IS_OUT_OF_RANGE,
    JSON_ERR_TOKENID_IS_NOT_OBJECT,
    JSON_ERR_VESSLE_IS_NULL,
    JSON_ERR_VESSLE_TOKENS_IS_NULL,
    JSON_ERR_VESSLE_TOKENS_COUNT_ZERO,
    JSON_ERR_VESSLE_TOKENS_COUNT_NEGATIVE,
    JSON_ERR_VESSLE_JSON_IS_NULL,
    JSON_ERR_VESSLE_JSON_IS_TOO_SHORT,
    JSON_ERR_VESSLE_JSON_IS_TOO_LONG,

} json_err_t;

typedef struct _js_vessel_
{
    jsmntok_t *tokens;
    string json;
    int tokens_count;
} js_vessel_t;

typedef struct __jk_list__
{
    string key;      // if key is null, this means the key is high level array, eg: array[4][2][1]
    int array_index; // if array_index is -1, this means the key is not a array name or the array index is not set
    struct __jk_list__ *next;
} jk_list_t;

/* Exported variables --------------------------------------------------------*/

/* Exported function prototypes ----------------------------------------------*/

// user function
void print_token_list(js_vessel_t *js_vessel);
void print_token(js_vessel_t *js_vessel, int token_id);
void print_json(js_vessel_t *js_vessel);
int get_json_token_count(js_vessel_t *js_vessel);
int get_json_token_length(js_vessel_t *js_vessel, int token_id);
string json_err_to_string(json_err_t err);

json_err_t read_json_file(string path, byte **out, bool_t non_space);
json_err_t parse_json_buffer(js_vessel_t *js_vessel);
json_err_t free_json_vessel(js_vessel_t *js_vessel);
json_err_t check_json_vessel(js_vessel_t *js_vessel);

json_err_t get_content_by_path(js_vessel_t *js_vessel, string path, string out, string default_value, int max_len);
json_err_t get_number_by_path(js_vessel_t *js_vessel, string path, int *out, int default_value);
json_err_t get_string_by_path(js_vessel_t *js_vessel, string path, string out, string default_value, int max_len);
json_err_t get_string_by_path_alloc(js_vessel_t *js_vessel, string path, string *out, string default_value, int max_len);
json_err_t get_array_size_by_path(js_vessel_t *js_vessel, string path, int *out);
json_err_t get_bool_by_path(js_vessel_t *js_vessel, string path, bool *out, bool default_value);

#endif /* __JSMN_PARSER_H__ */
/************************ (C) COPYRIGHT PURESUN *****END OF FILE****************/
